package lzupdater.utils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import lzupdater.locale.LocalizedString;

//LZRosterUpdater, a java client to update LZRoster
//Copyright (C) 2008 Fraskor from Krasus (e-mail: fraskor@gmail.com)

//This file is part of LZRosterUpdater.

//LZRosterUpdater is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

public abstract class WoWPathGuesser {
	
	private static final LocalizedString tooltipText = new LocalizedString("Select the World of Warcraft application");
	private static final LocalizedString select = new LocalizedString("Select");
	
	
	protected abstract String guessExecutablePath(String rootPath);
	protected abstract Map<String, String> guessLZProfilerPath(String rootPath);
	protected abstract String getApplicationName();
	protected abstract String guessAccountPath(String rootPath);
	
	public abstract String getRootPath();

	
	public String getRootPathOrAsk() {
		String rootPath = getRootPath();
		
		if (rootPath == null) {
			rootPath = browseToRootPath();
		}
		
		return rootPath;
	}

	public String browseToRootPath() {
		JFileChooser jfc = new JFileChooser();
		FileFilter filter = new FileFilter() {

			@Override
			public boolean accept(File f) {
				return (f.isDirectory() && !f.getName().endsWith(".app")) || f.getName().equals(getApplicationName());
			}

			@Override
			public String getDescription() {
				return getApplicationName();
			}
			
		};
		
		jfc.setFileFilter(filter);
		jfc.setDialogTitle(tooltipText.toString());
		int result = jfc.showDialog(null, select.toString());

		
		if (result == JFileChooser.APPROVE_OPTION) {
			return jfc.getSelectedFile().getParent();
		}
		return null;
	}
	
	public String getExecutablePath(String rootPath) {
		if (rootPath != null) return guessExecutablePath(rootPath);
		return null;
	}
	
	public Map<String, String> getLZProfilerPath(String rootPath) {
		if (rootPath != null) return guessLZProfilerPath(rootPath);
		return null;
	}
		
	public String getLZProfilerBrowsePath(String rootPath) {
		if (rootPath == null) return null;
		Map<String, String> accounts = getLZProfilerPath(rootPath);

		if (accounts.isEmpty()) {
			return null;
		}
		else if (accounts.size() == 1) {
			return accounts.values().iterator().next();
		} 
		else {
			return guessAccountPath(rootPath);
		}
	
	}
	
	public static WoWPathGuesser getInstance() {
		String currentOsName = System.getProperty("os.name");
		
		if (currentOsName == null) return new WoWPathGuesserDefault();
		
		currentOsName = currentOsName.toLowerCase();
		
		if (currentOsName.contains("windows")) {
			return new WoWPathGuesserWindows();
		}
		else if (currentOsName.contains("os x")) {
			return new WoWPathGuesserOSX();
		}
		else {
			return new WoWPathGuesserDefault();
		}
	}



	private static class WoWPathGuesserDefault extends WoWPathGuesser {

		@Override
		public String getRootPath() {
			return null;
		}

		@Override
		protected String guessExecutablePath(String rootPath) {
			return null;
		}

		@Override
		protected Map<String, String> guessLZProfilerPath(String rootPath) {
			return null;
		}

		@Override
		protected String getApplicationName() {
			return "";
		}
		
		@Override
		protected String guessAccountPath(String rootPath) {
			return null;
		}
		
		
	}


	private static class WoWPathGuesserWindows extends WoWPathGuesser {
		
		public String getRootPath() {
			File rootDir = new File("C:\\");
			if (!rootDir.exists() || !rootDir.isDirectory()) return null;

			// For Windows try to guess the path to the LZProfiler.lua file
			File[] progDirs = rootDir.listFiles(new java.io.FileFilter() {
				public boolean accept(File dir) {
					return new File(String.format(
							"%s\\World of Warcraft\\WoW.exe", dir.getAbsoluteFile()))
					.exists();
				}
			});

			if (progDirs.length == 0) return null;

			return String.format("%s\\World of Warcraft\\",progDirs[0].getAbsolutePath());
		}

		@Override
		protected String getApplicationName() {
			return "WoW.exe";
		}

		@Override
		protected String guessExecutablePath(String rootPath) {
			return String.format("%s\\%s", rootPath, getApplicationName());
		}

		/**
		 * 
		 */
		@Override
		protected Map<String, String> guessLZProfilerPath(String rootPath) {
			
			File accountDir = new File(String.format("%s\\WTF\\Account", rootPath));

			if (!accountDir.exists()) return null;

			File[] accounts = accountDir.listFiles(new java.io.FileFilter() {
				public boolean accept(File pathname) {
					return new File(String.format(
							"%s\\SavedVariables", pathname.getAbsolutePath())).exists();
				}
			});

			Map<String, String> resultat = null;
			if (accounts.length > 0) {
				resultat = new HashMap<String, String>();
				for (File account : accounts) {
					resultat.put(account.getName(), String.format("%s\\SavedVariables\\LZProfiler.lua", account.getAbsolutePath()));
				}
			}

			return resultat;
		}
		
		@Override
		protected String guessAccountPath(String rootPath) {
			return String.format("%s\\WTF\\Acount", rootPath);
		}
		
	}
	
	
	private static class WoWPathGuesserOSX extends WoWPathGuesser {

		@Override
		public String getRootPath() {
			File rootDir = new File("/");
			if (!rootDir.exists() || !rootDir.isDirectory()) return null;

			// For Windows try to guess the path to the LZProfiler.lua file
			File[] progDirs = rootDir.listFiles(new java.io.FileFilter() {
				public boolean accept(File dir) {
					return new File(String.format(
							"%s/World of Warcraft/World of Warcraft.app", dir.getAbsoluteFile()))
					.exists();
				}
			});

			if (progDirs.length == 0) return null;
			
			return String.format("%s/World of Warcraft",progDirs[0].getAbsolutePath());
		}

		@Override
		protected String getApplicationName() {
			return "World of Warcraft.app";
		}

		protected String guessExecutablePath(String rootPath) {
			return String.format("%s/%s/Contents/MacOS/World of Warcraft", rootPath, getApplicationName());
		}
		
		
		@Override
		protected Map<String, String> guessLZProfilerPath(String rootPath) {
			
			File accountDir = new File(String.format("%s/WTF/Account", rootPath));

			if (!accountDir.exists()) return null;

			File[] accounts = accountDir.listFiles(new java.io.FileFilter() {
				public boolean accept(File pathname) {
					return new File(String.format(
							"%s/SavedVariables", pathname.getAbsolutePath())).exists();
				}
			});

			Map<String, String> resultat = null;
			if (accounts.length > 0) {
				resultat = new HashMap<String, String>();
				for (File account : accounts) {
					resultat.put(account.getName(), String.format("%s/SavedVariables/LZProfiler.lua", account.getAbsolutePath()));
				}
			}

			return resultat;

		
		}

		@Override
		protected String guessAccountPath(String rootPath) {
			return String.format("%s/WTF/Acount", rootPath);
		}

		
	}
}